org	07c00h
jmp	short	LABEL_START
	nop
	BS_OEMName	DB 'IBM  3.3'	; OEM String, 必须 8 个字节
	BPB_BytsPerSec	DW 512		; 每扇区字节数
	BPB_SecPerClus	DB 1		; 每簇多少扇区
	BPB_RsvdSecCnt	DW 1		; Boot 记录占用多少扇区
	BPB_NumFATs	DB 2		; 共有多少 FAT 表
	BPB_RootEntCnt	DW 224		; 根目录文件数最大值
	BPB_TotSec16	DW 2880		; 逻辑扇区总数
	BPB_Media	DB 0xF0		; 媒体描述符
	BPB_FATSz16	DW 9		; 每FAT扇区数
	BPB_SecPerTrk	DW 18		; 每磁道扇区数
	BPB_NumHeads	DW 2		; 磁头数(面数)
	BPB_HiddSec	DD 0		; 隐藏扇区数
	BPB_TotSec32	DD 0		; wTotalSectorCount为0时这个值记录扇区数
	BS_DrvNum	DB 0		; 中断 13 的驱动器号
	BS_Reserved1	DB 0		; 未使用
	BS_BootSig	DB 29h		; 扩展引导标记 (29h)
	BS_VolID	DD 0		; 卷序列号
	BS_VolLab	DB 'Angel0.001'; 卷标, 必须 11 个字节
	BS_FileSysType	DB 'FAT12   '	; 文件系统类型, 必须 8个字节  
LABEL_START:
	mov	ax,cs
	mov	ds,ax
	mov	es,ax
	mov ss,ax	
	mov sp,0100h
LABEL_SEARCH:
	mov byte[_SizeDir],SizeDir
	mov byte[_StartDir],StartDir 
	cmp byte[_SizeDir],0
	jz LABEL_OVER
	mov ax,BaseOfLoader	;加载段选择子 只能用ax
	mov es,ax
	mov bx,OffsetOfLoader
	xor eax,eax
	mov al,byte[_StartDir]
	push ax
	call LABEL_READ
	add sp,2
LABEL_FOR:
	mov al,byte[Index]
	cmp al,MAXIndex
	jz LABEL_OVER
	push FileSize		;压入文件名大小
	call LABEL_CMP		;调用字符串比较函数
	add sp,2
	cmp ax,0		;返回比较结果
	jz LABEL_FIND
	add bx,32		;每个目录项的大小为32byte
	inc byte[Index]		;增加index
	jmp LABEL_FOR
	xor eax,eax
	add byte[_StartDir],2
	mov al,byte[_StartDir]
	sub byte[_SizeDir],2
	jmp LABEL_SEARCH
LABEL_OVER:
	jmp 	$
	nop
	nop
LABEL_FIND:
	xor edi,edi
	xor eax,eax
	mov di,bx
	add di,01Ah
	mov ax,word[es:di]
	mov word[FirstClus],ax
	push ax
	call LABEL_LOADE_FILE
	add sp,2
LABEL_FAT:
	mov byte[_SizeFat],SizeFat
.3:	cmp byte[_SizeFat],0
	jz  LABEL_OVER	
	mov ax,BaseOfLoader
	sub ax,0100h        ;用于存放FAT
	mov es,ax
	mov bx,OffsetOfLoader
	xor ax,ax
	mov ax,word[FirstClus] ;簇编号
	call LABEL_GETFAT
	cmp ax,0FFFh
	jz LABEL_GO
	mov word[FirstClus],ax
	push ax
	call LABEL_LOADE_FILE
	add sp,2
	mov ax,word[FirstClus] ;for debug 
	sub byte[_SizeFat],2
	jmp .3
LABEL_GETFAT:
	xor dx,dx
	xor bx,bx
	mov bx,3
	mul bx   	;ax=ax*3
	xor bx,bx
	mov bx,2
	div bx		;ax/2 =>商在ax,余数在dx
	
	push ax
	push dx
	xor dx,dx
	mov bx,BPB_BytsPerSec;每簇字节数
	div bx			;ax为相对扇区
	add ax,StartFat
	mov bx,OffsetOfLoader
	push ax
	mov byte[BLOCK],2
	call LABEL_READ
	add sp,2	;实模式下
	mov byte[_Flag],0
	xor dx,dx
	pop dx
	cmp dx,0
	jz LABEL_ODD
	mov byte[_Flag],1
LABEL_ODD:
	pop ax
	add bx,ax
	xor ax,ax
	mov ax,[es:bx]
	cmp byte[_Flag],1
	jnz LABEL_EVEN
	shr ax,4
	ret
LABEL_EVEN: ;偶数
	and ax,0fffh
	ret
LABEL_GO:
	jmp BaseOfLoader:OffsetOfLoader
LABEL_LOADE_FILE:
	push bp
	mov bp,sp
	mov ax,BaseOfLoader
	mov es,ax
	mov bx,OffsetOfLoader
	add bx,word[index]
	xor eax,eax
	mov ax,[bp+4] ;读取扇区数
	add ax,RootDirSectors	;算数扇区数
	mov byte[BLOCK],1 ;只读取一扇区
	push ax
	call LABEL_READ
	add sp,2
	pop bp
	add word[index],512
	ret
LABEL_CMP:
	push bp
	mov  bp,sp
	xor  esi,esi
	xor  ecx,ecx
	nop
	mov si,FileName		;ds:si=文件指针偏移
	mov cx,word[bp+4]		;cx=文件名大小
	xor edi,edi
	mov di,bx
	cld
.cmp:
	lodsb
	cmp al,byte[es:di]
	jnz .1
	inc di
	loop .cmp
	mov ax,0		;找到返回0
	pop bp	
	ret
.1:
	mov ax,1		;没有找到返回1
	pop bp
	ret
	
	
LABEL_READ:
;扇区号 x
	;                |商y 柱面号y>>1 磁头号y&1  
	; x/每磁道扇区数=| 
	;                |余数z 起始扇区号z+1
	push bp
	mov bp,sp
.1:	xor eax,eax
	mov ax,[bp+4]  		;扇区号
	xor dx,dx
	push bx
	mov bx,SecPerTrk 	;每磁道扇区数
	div bx  		;商y=ax,余数z=dx
	push ax
	shr al,1		;柱面号=y>>1
	mov ch, al		;ch=al>>1
	pop ax
	and al,1		;磁头号=y&1
	mov dh,al		;dh=y&1
	add dl,1		;起始扇区号=z+1
	mov cl,dl		;cl=z+1
	mov al,byte[BLOCK]	;读取扇区数
	mov ah,2		;BIOS 中断ah=2
	pop bx
	mov dl,0		;dl=驱动器号
	int 13h			;BOIS 中断号
	cmp ah,0		;读成功ah=0
	jnz .1
	pop bp
	ret	
BaseOfLoader equ  09000h
OffsetOfLoader equ 0100h
StartDir	equ	19  ;目录项开始扇区
SizeDir		equ	14  ;目录项总共扇区数目
_SizeDir	db 	0   ;
_StartDir	db	0   ;
index		dw      0
StarFat		equ	1   ;FAT表开始扇区
SizeFat	equ	9	    ;FAT表总共扇区数目
SecPerTrk	equ	18  ;每磁道扇区数
FileName db "LOADER  BIN",0   ;要查找的文件名
Index	db	0
dest    dw       0
RootDirSectors equ 31
FirstClus dw    0		;第一簇
BLOCK 	db	2
MAXFATIndex  equ 	9	;FAT最大扇区数
MAXIndex	equ	32	;1k中最大目录结构
StartFat	equ	1
_SizeFat    	db	0
_Flag db 0
FileSize equ	11	    ;文件名大小
times	510-($-$$)	db	0
dw	0xaa55	
